# -*- coding: utf-8 -*-

import gtk
import imn_conf
import imn_xmpp
import gobject
import hildon
import webbrowser
import os

gui = {}

def init_gui( exec_path, desk ):
    xmpp_cli = imn_xmpp.imn_xmpp()
    gui['xmpp_cli'] = xmpp_cli
    
    conf_data = {}
    gui['conf_data'] = conf_data

    hildon_program = hildon.Program()
    gui['hildon_program'] = hildon_program
    hildon_program.__init__()
    
    
    main_window = hildon.Window()
    gui['main_window'] = main_window
    main_window.set_title("imnext")
    main_window.resize(300,200)
    main_window.connect("destroy",destroy)

    hildon_program.add_window( main_window )

    # Setting up the icon for the window
    icon_theme = gtk.icon_theme_get_default()
    try:
        pixbuf = icon_theme.load_icon("imnext", 48, 0)
        gtk.window_set_default_icon(pixbuf)
    except gobject.GError, exc:
        icon_path = os.path.join(os.path.dirname(os.path.dirname(os.path.abspath(exec_path))),'data', '48x48','imnext.png')
        
        pixbuf = gtk.gdk.pixbuf_new_from_file(icon_path)
        gtk.window_set_default_icon(pixbuf)

    
    vbox = gtk.VBox()
    main_window.add(vbox)


    # Menus
    file_menu = gtk.Menu()
    
    new_item = gtk.ImageMenuItem(gtk.STOCK_NEW)
    file_menu.append(new_item)
    new_item.connect('activate', menu_new, gui )

    connect_item = gtk.ImageMenuItem(gtk.STOCK_CONNECT)
    file_menu.append(connect_item)
    connect_item.connect('activate', menu_connect, gui )

    disconnect_item = gtk.ImageMenuItem(gtk.STOCK_DISCONNECT)
    file_menu.append(disconnect_item)
    disconnect_item.connect('activate', menu_disconnect, gui )

    file_menu.append( gtk.SeparatorMenuItem() )

    quit_item = gtk.ImageMenuItem(gtk.STOCK_QUIT)
    file_menu.append(quit_item)
    quit_item.connect("activate", destroy, "file.quit")


    conf_menu = gtk.Menu()

    set_position_item = gtk.MenuItem('Registra posição')
    conf_menu.append(set_position_item)
    set_position_item.connect('activate', menu_set_position, gui)


    help_menu = gtk.Menu()

    about_item = gtk.ImageMenuItem(gtk.STOCK_ABOUT)
    help_menu.append(about_item)
    about_item.connect('activate', show_about_dialog)


    mi_arquivo = gtk.MenuItem('Arquivo')
    mi_arquivo.set_submenu(file_menu)

    mi_conf = gtk.MenuItem('Configurações')
    mi_conf.set_submenu(conf_menu)

    mi_help = gtk.MenuItem('Ajuda')
    mi_help.set_submenu(help_menu)

    if desk:
        menubar = gtk.MenuBar()
        vbox.pack_start( menubar, False, False, 0 )

        menubar.add( mi_arquivo )
        menubar.add( mi_conf )
        menubar.add( mi_help )
    else:
        all_menu = gtk.Menu()

        all_menu.append( mi_arquivo )
        all_menu.append( mi_conf )
        all_menu.append( mi_help )
        
        hildon_program.set_common_menu(all_menu)
        all_menu.show_all()
    

    # End Menus

    hbox = gtk.HBox()
    vbox.pack_start( hbox )

    buddy_list = gtk.ListStore(str)
    gui['buddy_list'] = buddy_list

    buddy_tree = gtk.TreeView(buddy_list)
    gui['buddy_tree'] = buddy_tree
    # A linha abaixo deve ser descomentada caso a lista de amigos
    #queira ser usada.
    #hbox.pack_end(buddy_tree)

    
    tvcolumn = gtk.TreeViewColumn('Amigos')
    buddy_tree.append_column( tvcolumn )
    
    cell = gtk.CellRendererText()
    tvcolumn.pack_start(cell, True)
    tvcolumn.add_attribute(cell, 'text',0)


    next_list = gtk.ListStore(str)
    gui['next_list'] = next_list

    next_tree = gtk.TreeView(next_list)
    gui['next_tree'] = next_tree
    hbox.pack_end(next_tree)

    tvcolumn = gtk.TreeViewColumn('Next')
    next_tree.append_column( tvcolumn )

    cell = gtk.CellRendererText()
    tvcolumn.pack_start(cell, True)
    tvcolumn.add_attribute(cell, 'text',0)

    
    notebook_area = gtk.Notebook()
    gui['notebook_area'] = notebook_area
    hbox.pack_start(notebook_area)

    vbox_chat = gtk.VBox()
    notebook_area.append_page( vbox_chat, gtk.Label('Chat') )
    
    chat_buffer = gtk.TextBuffer()
    gui['chat_buffer'] = chat_buffer

    scrolled = gtk.ScrolledWindow()
    scrolled.set_policy(gtk.POLICY_NEVER, gtk.POLICY_AUTOMATIC)
    
    vbox_chat.pack_start( scrolled )
    chat_view = gtk.TextView(chat_buffer)
    gui['chat_view'] = chat_view
    scrolled.add(chat_view)
    chat_view.set_property("editable", False)
    chat_view.set_property("cursor-visible", False)
    chat_view.set_property("wrap-mode", gtk.WRAP_WORD)

    hbox_send_area = gtk.HBox()
    vbox_chat.pack_end( hbox_send_area, False, False )

    entry_chat = gtk.Entry()
    gui['entry_chat'] = entry_chat
    hbox_send_area.pack_start( entry_chat )
    entry_chat.connect('activate',send_message_button, gui )

    send_button = gtk.Button("Enviar")
    gui['send_button'] = send_button
    hbox_send_area.pack_end( send_button , False, False)
    send_button.connect('clicked', send_message_button, gui )


    status_bar = gtk.Statusbar()
    gui['status_bar'] = status_bar
    vbox.pack_end(status_bar, False, False)
    gui['context_conn'] = status_bar.get_context_id("connected")
    gui['context_disc'] = status_bar.get_context_id("disconnected")
    status_bar.push(gui['context_disc'], "Desconectado")

    load_conf_file(gui)
    
    return gui


def show_about_dialog( menu_item ):
    gtk.about_dialog_set_url_hook( open_browser, 'http://imnext.googlecode.com' )

    dia = gtk.AboutDialog()

    dia.set_name( 'IM Next' )
    dia.set_version( '1.0' )
    dia.set_copyright( 'GPL 2')
    dia.set_comments( 'A instant messenger that you can talk with people next to your location.' )
    dia.set_website_label( 'IM Next Website' )
    dia.set_website('http://imnext.googlecode.com')
    dia.set_authors(['Thiago C. Fernandes'])
    dia.set_program_name('IM Next')


    dia.run()

    dia.destroy()


def open_browser( dialog, url, data ):
    webbrowser.open(url)
    
    
def save_conf_file():
    global gui

    conf = gui['conf_data']
    if gui['xmpp_cli'].get_username() != '' and gui['xmpp_cli'].get_password() != '':
        imn_conf.fill_conf_data( gui['xmpp_cli'], conf )
        imn_conf.write_conf( conf )


def load_conf_file(gui):
    conf = gui['conf_data']

    conf_data = imn_conf.read_conf()

    if conf_data <> {}:
        gui['xmpp_cli'].init( conf_data['username'],
                              conf_data['password'],
                              message_arrived,
                              update_next_list)

        for each in conf_data['friends_list']:
            gui['xmpp_cli'].add_friend(each)

        gui['xmpp_cli'].set_position( conf_data['user_position'] )
        gui['xmpp_cli'].set_location( conf_data['user_location'] )

        load_buddy_interface( gui )
        gui['status_bar'].push( gui['context_disc'], "Usuário: %s desconectado"%gui['xmpp_cli'].get_username())
    

def menu_set_position( item, gui ):
    dialog_pos = gtk.Dialog("Registrar posição",
                            None,
                            gtk.DIALOG_MODAL | gtk.DIALOG_DESTROY_WITH_PARENT,
                            (gtk.STOCK_CANCEL, gtk.RESPONSE_REJECT,
                             gtk.STOCK_OK, gtk.RESPONSE_ACCEPT))

    dialog_pos.vbox.pack_start( gtk.Label('Onde estou?'), False, False )
    location_entry = gtk.Entry()
    location_entry.set_text(gui['xmpp_cli'].get_location())
    dialog_pos.vbox.pack_start( location_entry )

    dialog_pos.show_all()
    response = dialog_pos.run()

    if response == gtk.RESPONSE_ACCEPT:
        location = location_entry.get_text()
        if gui['xmpp_cli'].set_location( location ):
            gui['status_bar'].push( gui['context_disc'], "Usuário: %s desconectado"%gui['xmpp_cli'].get_username())
        else:
            gui['status_bar'].push( gui['context_disc'], "Não sei onde esta você")


    dialog_pos.destroy()
    

def send_message_button( button, gui ):
    text_to_send = gui['entry_chat'].get_text()
    treeselection = gui['next_tree'].get_selection()

    (model, iter) = treeselection.get_selected()

    if iter != None:
        buddy = model.get_value(iter, 0)

        gui['xmpp_cli'].send_message(buddy, text_to_send)

        gui['entry_chat'].set_text('')

        print_msg_buffer( "eu", text_to_send, gui['chat_buffer'],
                          gui['chat_view'])

        
def print_msg_buffer( whose, msg, buff, view ):
    msg = whose + ": " + msg + '\n'
    text_iter = buff.get_end_iter()
    buff.insert(text_iter, msg)
    view.scroll_to_mark(buff.get_insert(), 0)
    
    
def run_gui(gui):
    main_window = gui['main_window']
    main_window.show_all()

    gtk.main()


def destroy( widget, data=None ):

    save_conf_file()
    
    gtk.main_quit()
    

def menu_connect( menu_item, gui ):
    if gui['xmpp_cli'] <> None and gui['xmpp_cli'].is_initiated() and gui['xmpp_cli'].get_location() <> '' and not gui['xmpp_cli'].is_connected():
        if gui['xmpp_cli'].connect():
            gui['event_io_id'] = gobject.io_add_watch( gui['xmpp_cli']._client.Connection._sock,
                                  gobject.IO_IN,
                                  process_message,
                                  gui )
            gui['xmpp_cli'].register_within_imnext_bot()

            gui['status_bar'].push( gui['context_conn'], "Usuário: %s conectado"%gui['xmpp_cli'].get_username())

            
def menu_disconnect( menu_item, gui ):
    if gui['xmpp_cli'] <> None and gui['xmpp_cli'].is_initiated() and gui['xmpp_cli'].is_connected():
        username = gui['xmpp_cli'].get_username()
        password = gui['xmpp_cli'].get_password()
        func1 = gui['xmpp_cli'].get_msg_arr_func()
        func2 = gui['xmpp_cli'].get_sign_update_next_list()
        if gui['xmpp_cli'].disconnect():
            gobject.source_remove(gui['event_io_id'])
            clean_next_list( gui['next_list'] )
            gui['xmpp_cli'].init(username, password, func1, func2 )
            gui['status_bar'].push( gui['context_disc'], "Usuário: %s desconectado"%gui['xmpp_cli'].get_username())

            
def process_message(source, cb_condition, gui ):
    gui['xmpp_cli']._client.Process(1)

    return True

                                  
def message_arrived( fromjid, body ):
    global gui
    print_msg_buffer( fromjid, body, gui['chat_buffer'],
                      gui['chat_view'])

            
def menu_new( self, gui ):
    new_user = gtk.Dialog( "Novo usuário",
                           None,
                           gtk.DIALOG_MODAL | gtk.DIALOG_DESTROY_WITH_PARENT,
                           (gtk.STOCK_CANCEL, gtk.RESPONSE_REJECT,
                            gtk.STOCK_OK, gtk.RESPONSE_ACCEPT) )
    new_user.vbox.pack_start( gtk.Label('Usuário (no servidor jabber.org)'), False, False )
    user_entry = gtk.Entry()
    user_entry.set_text(gui['xmpp_cli'].get_username())
    new_user.vbox.pack_start( user_entry )

    new_user.vbox.pack_start( gtk.Label('Senha') )
    pass_entry = gtk.Entry()
    pass_entry.set_property("visibility", False)
    pass_entry.set_text(gui['xmpp_cli'].get_password())
    new_user.vbox.pack_start( pass_entry )

    new_user.vbox.pack_start( gtk.Label('Onde estou?'), False, False )
    location_entry = gtk.Entry()
    location_entry.set_text(gui['xmpp_cli'].get_location())
    new_user.vbox.pack_start( location_entry )

    new_user.show_all()
    response = new_user.run()

    if response == gtk.RESPONSE_ACCEPT:
        gui['xmpp_cli'].init( user_entry.get_text(),
                              pass_entry.get_text(),
                              message_arrived,
                              update_next_list )
        location = location_entry.get_text()
        if gui['xmpp_cli'].set_location( location ):
            gui['status_bar'].push( gui['context_disc'], "Usuário: %s desconectado"%gui['xmpp_cli'].get_username())
        else:
            gui['status_bar'].push( gui['context_disc'], "Não sei onde esta você")

    new_user.destroy()

    
def menu_add_friend( self, gui ):
    new_friend = gtk.Dialog("Novo amigo",
                            None,
                            gtk.DIALOG_MODAL | gtk.DIALOG_DESTROY_WITH_PARENT,
                            (gtk.STOCK_CANCEL, gtk.RESPONSE_REJECT,
                             gtk.STOCK_OK, gtk.RESPONSE_ACCEPT))
    new_friend.vbox.pack_start( gtk.Label('Endereço do amigo'), False, False )
    user_entry = gtk.Entry()
    new_friend.vbox.pack_start( user_entry )

    new_friend.show_all()
    response = new_friend.run()

    if response == gtk.RESPONSE_ACCEPT:
        gui['xmpp_cli'].add_friend( user_entry.get_text() )

    new_friend.destroy()
    load_buddy_interface( gui )
    

    
def update_next_list():
    gui['next_list'].clear()
    for each in gui['xmpp_cli'].get_next_list():
        gui['next_list'].append([each])
    

    
def menu_rm_friend( self, gui ):
    old_friend = gtk.Dialog("Remover amigo",
                            None,
                            gtk.DIALOG_MODAL | gtk.DIALOG_DESTROY_WITH_PARENT,
                            (gtk.STOCK_CANCEL, gtk.RESPONSE_REJECT,
                             gtk.STOCK_OK, gtk.RESPONSE_ACCEPT))
    old_friend.vbox.pack_start( gtk.Label('Endereço do amigo'), False, False )
    user_entry = gtk.Entry()
    old_friend.vbox.pack_start( user_entry )

    old_friend.show_all()
    response = old_friend.run()

    if response == gtk.RESPONSE_ACCEPT:
        gui['xmpp_cli'].rm_friend( user_entry.get_text() )

    old_friend.destroy()
    load_buddy_interface( gui )

    
def load_buddy_interface( gui ):
    gui['buddy_list'].clear()
    for each in gui['xmpp_cli'].get_friends_list():
        gui['buddy_list'].append([each])


def clean_next_list( next_list ):
    next_list.clear()
